//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Web.UI;
using CommunityServer.Components;
using CommunityServer.Discussions.Components;

namespace CommunityServer.Discussions.Controls
{
	/// <summary>
	/// Summary description for RatePost.
	/// </summary>
	public class RatePost : CommunityServer.Controls.RatingControl
	{

        protected CSContext csContext = CSContext.Current;


		private string _viewDetailsScript = null;
		public override string ViewDetailsScript
		{
			get
			{
				if (_viewDetailsScript == null)
					_viewDetailsScript = "OpenWindow('" + Globals.GetSiteUrls().PostRating(this.ThreadID) + "')";

				return _viewDetailsScript;
			}
			set
			{
				_viewDetailsScript = value;
			}
		}

		private int _currentVotes = -1;
		public override int CurrentVotes
		{
			get
			{
				if (_currentVotes == -1)
				{
					SectionRatingType ratingType = csContext.SiteSettings.SectionRatingType;

					if (ratingType == SectionRatingType.ThreadRating)
					{
						_currentVotes = this.Thread.TotalRatings;
					}
					else if (ratingType == SectionRatingType.PostRating)
					{
						_currentVotes = this.Post.TotalRatings;
					}
					else
						_currentVotes = 0;
				}

				return _currentVotes;
			}
			set
			{
				_currentVotes = value;
			}
		}

		private double _currentRating = -1;
		public override double CurrentRating
		{
			get
			{
				if (_currentRating == -1)
				{
					SectionRatingType ratingType = csContext.SiteSettings.SectionRatingType;

					if (ratingType == SectionRatingType.ThreadRating)
					{
						_currentRating = this.Thread.RatingAverage;
					}
					else if (ratingType == SectionRatingType.PostRating)
					{
						_currentRating = this.Post.RatingAverage;
					}
					else
						_currentRating = 0;
				}

				return _currentRating;
			}
			set
			{
				_currentRating = value;
			}
		}

		public override bool UserCanRate 
		{ 
			get
			{
				return !csContext.User.IsAnonymous;
			}
		}

		public override void Rate(double value)
		{
			SectionRatingType ratingType = csContext.SiteSettings.SectionRatingType;
			Rating rating = new Rating();
			rating.User = csContext.User;
			rating.Value = (int) value;
	
			if (ratingType == SectionRatingType.ThreadRating)
			{
				int currentRating = Ratings.GetRating(RatingType.Thread, this.ThreadID, csContext.User.UserID);

				rating.RatingType = RatingType.Thread;
				rating.ItemID = this.ThreadID;
				Ratings.Rate(rating);

				if (currentRating == -1)
				{
					_currentVotes = this.Thread.TotalRatings + 1;
					_currentRating = (this.Thread.RatingSum + value) / (this.Thread.TotalRatings + 1);
				}
				else
					_currentRating = ((this.Thread.RatingSum - currentRating) + value) / this.Thread.TotalRatings;

				CSCache.RemoveByPattern(string.Format("Forum-Threads::S:{0}", Thread.SectionID));
				CSCache.RemoveByPattern(string.Format("Forum-Threads::S:{0}", -1));
				CSCache.RemoveByPattern(string.Format("Forum-Posts::P:{0}", Thread.PostID));
			}
			else if (ratingType == SectionRatingType.PostRating)
			{
				int currentRating = Ratings.GetRating(RatingType.Post, this.PostID, csContext.User.UserID);

				rating.RatingType = RatingType.Post;
				rating.ItemID = this.PostID;
				Ratings.Rate(rating);

				if (currentRating == -1)
				{
					_currentVotes = this.Post.TotalRatings + 1;
					_currentRating = (this.Post.RatingSum + value) / (this.Post.TotalRatings + 1);
				}
				else
					_currentRating = ((this.Post.RatingSum - currentRating) + value) / this.Post.TotalRatings;

				CSCache.RemoveByPattern(string.Format("Forum-Threads::S:{0}", Post.SectionID));
				CSCache.RemoveByPattern(string.Format("Forum-Threads::S:{0}", -1));
				CSCache.RemoveByPattern(string.Format("Forum-Posts::P:{0}", Post.PostID));
				if(Post.PostLevel > 1)
					CSCache.RemoveByPattern(string.Format("Forum-Posts::P:{0}.*", Post.ParentID));
			}
		}

		public virtual int PostID
		{
			get
			{
				Object state = ViewState["Post"];
				if (state == null)
					return -1;
				else
					return (int) state;
			}
			set
			{
				ViewState["Post"] = value;
			}
		}

        public virtual Post Post 
        {
            get 
            {
                if ( _post == null ) 
                {
                    Object state = ViewState["Post"];
                    if ( state != null ) 
                    {
                        Int32 postID = (Int32)state;
                        _post = Posts.GetPost( postID, csContext.User.UserID, false );
                    }
                }
                return _post;
            }
            set 
            {
                _post = value;
                if ( _post != null ) 
                {
                    ViewState[ "Post" ] = _post.PostID;
                } 
                else 
                {
                    ViewState.Remove( "Post" );
                }
            }
        }
	    Post _post;

		Thread _thread;
		public virtual Thread Thread
		{
			get
			{
				if (_thread == null)
				{
					Object state = ViewState["Thread"];
					if ( state != null ) 
					{
						Int32 threadID = (Int32)state;
						_thread = Threads.GetThread(threadID);
					}
					else if ( Post != null )
					{
						_thread = Threads.GetThread(Post.ThreadID);
					}
				}

				return _thread;
			}
			set
			{
				_thread = value;
				if ( _thread != null ) 
				{
					ViewState[ "Thread" ] = _thread.ThreadID;
				} 
				else 
				{
					ViewState.Remove( "Thread" );
				}
			}
		}

		public virtual int ThreadID
		{
			get
			{
				Object state = ViewState["Thread"];
				if (state == null)
				{
					if (Post != null)
					{
						ThreadID = Post.ThreadID;
						return Post.ThreadID;
					}
					else
						return -1;
				}
				else
					return (int) state;
			}
			set
			{
				ViewState["Thread"] = value;
			}
		}
	}
}
